<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>event_loop</title>
</head>

<body>
    <h3>event loop</h3>
    <p> https://blog.csdn.net/qq_61233877/article/details/124349171</p>

    事件循环（event loop）就是 任务在主线程不断进栈出栈的一个循环过程。任务会在将要执行时进入主线程，在执行完毕后会退出主线程。
    下面就是这个循环的步骤：
    1.把同步任务队列 或者 微任务队列 或者 宏任务队列中的任务放入主线程。
    2.同步任务 或者 微任务 或者 宏任务在执行完毕后会全部退出主线程。
    在实际场景下大概是这么一个顺序：
    <ol>
        <li>1.把同步任务相继加入同步任务队列。</li>
        <li>2.把同步任务队列的任务相继加入主线程。</li>
        <li>3.待主线程的任务相继执行完毕后，把主线程队列清空。</li>
        <li>4.把微任务相继加入微任务队列。</li>
        <li>5.把微任务队列的任务相继加入主线程。</li>
        <li>6.待主线程的任务相继执行完毕后，把主线程队列清空。</li>
        <li>7.把宏任务相继加入宏任务队列。无time的先加入，像网络请求。有time的后加入，像setTimeout(()=>{},time)，在他们中time短的先加入。</li>
        <li>8.把宏任务队列的任务相继加入主线程。</li>
        <li>9.待主线程的任务相继执行完毕后，把主线程队列清空。</li>
    </ol>

</body>
<script>
    setTimeout(() => { console.log(6) }, 2000)    // 任务a
    setTimeout(() => { console.log(4) })     // 任务 b
    setTimeout(() => { console.log(5) })     // 任务 c

    new Promise((rel) => {
        console.log(1)                         // 任务 d
        rel(3)
    })
        .then((res) => { console.log(res) })     // 任务 e

    console.log(2)                    // 任务 f

    // 打印结果：1,2,3,4,5,6

    let t1 = new Promise((resolve, reject) => {
        console.log(1);
        resolve(2);
        console.log(3);
    })
    t1.then(res => {
        console.log(res);
    });
    console.log(4);
    //打印结果: 1 3 4 2

</script>
<script>
    const tasks = []        // 主线程任务队列
    const syncTasks = []    // 同步任务队列
    const tinyTasks = []    // 微任务队列
    const macroTasks = []   // 宏任务队列

    // 第一次
    syncTasks.push('d', 'f')  // 首先同步任务d,f相继加入同步任务队列
    for (let t of syncTasks) { tasks.push(syncTasks.pop()) }   // 然后把同步任务队列的任务相继加入主线程   
    console.log(tasks)   // ['d','f']
    for (let t of tasks) { tasks.pop() }  // 在主线程相继执行完毕后，会相继出栈    
    console.log(tasks)    // []

    // 第二次
    tinyTasks.push('e')  // 首先微任务e加入微任务队列
    for (let t of tinyTasks) { tasks.push(tinyTasks.pop()) }   // 然后把微任务队列的任务相继加入主线程   
    console.log(tasks)  // ['e']
    for (let t of tasks) { tasks.pop() }  // 在主线程相继执行完毕后，会相继出栈    
    console.log(tasks)    // []

    // 第三次
    macroTasks.push('b', 'c')   // 首先宏任务'b','c'加入宏任务队列
    for (let t of macroTasks) { tasks.push(macroTasks.pop()) }   // 然后把宏任务队列的任务相继加入主线程   
    console.log(tasks)   // ['b','c']
    for (let t of tasks) { tasks.pop() }  // 在主线程相继执行完毕后，会相继出栈    
    console.log(tasks)    // []

    // 第四次
    macroTasks.push('a')   //  首先宏任务a加入宏任务队列
    for (let t of macroTasks) { tasks.push(macroTasks.pop()) }   // 然后把宏任务队列的任务相继加入主线程   
    console.log(tasks)   // ['a']
    for (let t of tasks) { tasks.pop() }  // 在主线程相继执行完毕后，会相继出栈    
    console.log(tasks)    // []

</script>

</html>